﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ThreadTest
{
    public partial class form : Form
    {
        public form()
        {
            InitializeComponent();
        }

        private void btnTask_Click(object sender, EventArgs e)
        {
            //1、调用task 的第一种方法 .Run()
            //Task1();
            //2、调用task 的第二种方法 Task.Factory
            //Task2();
            //3、需要多线程加快速度  同时又要求某个完成后，才能返回 多业务操作  希望并发，，但是某个完成后，才能返回
            //Task3();
            //4、回调 ContinueWhenAny、ContinueWhenAll
            //Task4();
            // 5、回调 ContinueWhenAny、ContinueWhenAll、WaitAny、WaitAll 一起使用
            //Task5();
            // 6、回调的一个状态 AsyncState
            //Task6();
            // 7 Task7
            Task7();
        }

        #region 1、调用task 的第一种方法 .Run()
        private void Task1()
        {
            int i = 0;
            Task task = Task.Run(() => this.DoSomething($"这是用Task调用的第一种方式{i++}"));
            Task task1 = Task.Run(new Action(() =>
            {
                Thread.Sleep(500);
                this.DoSomething($"这是用Task调用的第一种方式{i++}");
            }));
        }
        #endregion

        #region 2、调用task 的第二种方法 Task.Factory
        private void Task2()
        {
            Console.WriteLine($"****************btnTask_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

            Stopwatch watch = new Stopwatch();
            watch.Start();
            int i = 1;
            // 第一种定义方式
            TaskFactory taskFactory = Task.Factory; //new TaskFactory();
            taskFactory.StartNew(()=>this.DoSomething($"这是用Task调用的第二种方式00{i++}"));
            taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}"));
            taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}"));
            taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}"));
            taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}"));

            watch.Stop();

            Console.WriteLine($"****************btnTask_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}  耗时{watch.ElapsedMilliseconds}ms***************");
        }
        #endregion

        #region  3、WaitAll、WaitAny 卡界面
        private void Task3()
        {
            Console.WriteLine($"****************btnTask_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

            Stopwatch watch = new Stopwatch();
            watch.Start();
            int i = 1;

            TaskFactory taskFactory = Task.Factory; //new TaskFactory();
            List<Task> tasks = new List<Task>();
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));

            Task.WaitAny(tasks.ToArray());
            Console.WriteLine("只要完成一个，就会执行");

            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("全部任务都完成，才会执行");

            watch.Stop();
            Console.WriteLine($"****************btnTask_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}  耗时{watch.ElapsedMilliseconds}ms***************");
        }
        #endregion

        #region  4、回调 ContinueWhenAny、ContinueWhenAll 不会卡界面
        private void Task4()
        {
            Console.WriteLine($"****************btnTask_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

            Stopwatch watch = new Stopwatch();
            watch.Start();
            int i = 1;

            TaskFactory taskFactory = Task.Factory; //new TaskFactory();
            List<Task> tasks = new List<Task>();
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            // 回调
            taskFactory.ContinueWhenAny(tasks.ToArray(),t => Console.WriteLine($"ContinueWhenAny {Thread.CurrentThread.ManagedThreadId.ToString("00")}"));
            taskFactory.ContinueWhenAll(tasks.ToArray(), t => Console.WriteLine($"ContinueWhenAll {Thread.CurrentThread.ManagedThreadId.ToString("00")}"));

            Task.WaitAny(tasks.ToArray());
            Console.WriteLine("只有完成一个，才会执行");

            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("全部任务都完成，才会执行");

            watch.Stop();
            Console.WriteLine($"****************btnTask_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}  耗时{watch.ElapsedMilliseconds}ms***************");
        }
        #endregion

        #region  5、回调 ContinueWhenAny、ContinueWhenAll、WaitAny、WaitAll 一起使用
        private void Task5()
        {
            Console.WriteLine($"****************btnTask_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

            Stopwatch watch = new Stopwatch();
            watch.Start();
            int i = 1;

            TaskFactory taskFactory = Task.Factory; //new TaskFactory();
            List<Task> tasks = new List<Task>();
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            tasks.Add(taskFactory.StartNew(() => this.DoSomething($"这是用Task调用的第二种方式00{i++}")));
            // 回调
            tasks.Add(taskFactory.ContinueWhenAny(tasks.ToArray(), t => Console.WriteLine($"ContinueWhenAny {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));
            tasks.Add(taskFactory.ContinueWhenAll(tasks.ToArray(), t => Console.WriteLine($"ContinueWhenAll {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));

            Task.WaitAny(tasks.ToArray());
            Console.WriteLine("只有完成一个，才会执行");

            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("全部任务都完成，才会执行");

            watch.Stop();
            Console.WriteLine($"****************btnTask_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}  耗时{watch.ElapsedMilliseconds}ms***************");
        }
        #endregion

        #region 6、回调的一个状态 AsyncState
        private void Task6()
        {
            TaskFactory taskFactory = Task.Factory;
            Task task = taskFactory.StartNew(t => this.DoSomething("Task6"), "23");
            task.ContinueWith(t => Console.WriteLine($"这里是{t.AsyncState}的回调"));
        }
        #endregion


        #region 7、启动一个带返回的方法
        private void Task7()
        {
            TaskFactory taskFactory = Task.Factory;
            Task<int> intTask = taskFactory.StartNew(() => 123);
            int iResult = intTask.Result;
        }
        #endregion

        #region 一个私有的方法
        /// <summary>
        /// 一个私有的方法
        /// </summary>
        /// <param name="name"></param>
        private void DoSomething(string name)
        {
            Console.WriteLine($"****************DoSomethingLong Start {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
            long lResult = 0;
            for (int i = 0; i < 1000000000; i++)
            {
                lResult += i;
            }
            //Thread.Sleep(2000);

            Console.WriteLine($"****************DoSomethingLong   End {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
        }
        #endregion
    }
}
